﻿#include "iocpx.h"
template<typename m_>
bool iocpx_::start_iocp(DWORD dwlistenip, 
						unsigned short uslistenport, 
						DWORD dwmaxconnectnum, 
						DWORD dwrecvbufflen, 
						DWORD dwsendbufflen, 
						unsigned short usrecvbuffnum, 
						unsigned short ussendbuffnum, 
						iocpinterfacex_* piocpinterface)
{
	WSADATA wsaData;

	if (WSAStartup(0x0202, &wsaData) != 0)
		return false;
	GUID GuidAcceptEx = WSAID_ACCEPTEX;
	SYSTEM_INFO SysInfo;

	if (piocpinterface == NULL)
		return false;
	m_hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0);
	if (0 == m_hCompletionPort)
		return false;
	GetSystemInfo(&SysInfo);
	m_WorkerThreadNum  = SysInfo.dwNumberOfProcessors * 2;
	
	m_pworkthreadarr = new(nothrow) workerthreadx<m_>[m_WorkerThreadNum];
	if (m_pworkthreadarr == NULL)
		return false;
	for (int i = 0 ; i != m_WorkerThreadNum; ++i)
	{
		m_pworkthreadarr[i]->m_piocpx = this;
		m_pworkthreadarr[i]->Run();
	}
	m_plistenthread = new(nothrow) listenthreadx<m_>;
	if(m_plistenthread == NULL)
		return false;
	m_plistenthread->m_piocpx = this;
	m_plistenthread->m_sPort = uslistenport;
	m_plistenthread->Run();
	return true;
}
template<typename m_>
void iocpx_::handle_complate_notify(DWORD dwtrans,tcplinkx_<m_>* plink,pper_io_objx_ pperobject)
{
	switch(pperobject->operation)
	{
	case OP_ACCEPT:		//这是从Listen线程过来的消息
		{
			plink->m_recvobjx.operation = OP_RECV;
			plink->m_sendobjx.operation = OP_SEND;
			if (addlink(plink))
			{	
				if (handle_accept_link(plink))
					plink->post_recv();	
				else
					close_link(plink);
			}
			else
				close_link(plink);
		}
		break;
	case OP_RECV:
		{				
			if(dwtrans == 0)
			{
				//处理异常信息
				plink->m_brecv = false;
				close_link(plink);		
			}
			else
			{
				//处理该接受的数据	
				if(plink->onrecv(dwtrans))
					plink->post_recv();	
			} 
		}
		break;
	case OP_SEND:
		{
			if(dwtrans == 0)	
			{
				//处理异常信息
				plink->m_bsend = false;				
				close_link(plink);									
			}
			else
			{
				plink->onsend(dwtrans);	
			} 
		}
		break;
	default:
		break;
	}
}

template<typename m_>
bool iocpx_::handle_recv_msg(tcplinkx_<m_>* plink,char* pmsg,unsigned int uimsglen)
{
	if(uimsglen< sizeof(BaseMsgHead))
		return false;
	return m_handleinterface->on_recv_msg(pmsg,uimsglen,plink->m_dwpeerip,plink->m_usport,plink->m_dwSocketID);
}
template<typename m_>
bool iocpx_::handle_accept_link(tcplinkx_<m_>* plink)
{
	return m_handleinterface->on_accepted(plink->m_dwpeerip,plink->m_usport,plink->m_dwSocketID);
}
template<typename m_>
void iocpx_::handle_closed(tcplinkx_<m_>* plink)
{
	m_handleinterface->on_closed(plink->m_dwpeerip,plink->m_usport,plink->m_dwSocketID);
}